//
//  BBLibraryView.m
//  xNose
//
//  Created by ben smith on 9/10/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "BBLibraryView.h"
#import "BBLibraryController.h"
#import "BBNode.h"
#import "BBNodeViewFactory.h"
#import "BBAppController.h"
#import "BBViewThumbnailer.h"
#import "BBImageButtonFactory.h"
#import "BBLibraryNodeView.h"
#import "BBDragStrip.h"

@implementation BBLibraryView

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
			[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(closeTabNotification:) name:@"BBCloseLibraryNotification" object:nil];

			zoom = 1.0;
        // Initialization code here.

			float posFactor = [[NSUserDefaults standardUserDefaults] floatForKey:@"BBLibraryButtonPosition"];
			[[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@"BBLibraryButtonPosition" options:NSKeyValueObservingOptionNew context:nil];
			
			handleRect = NSMakeRect(0, (NSHeight([self bounds]) * posFactor) - 22.5, 45, 45);
//			NSButton * handle = [BBImageButtonFactory transparentButtonInRect:handleRect];
//			[handle setTarget:self];
//			[handle setAction:@selector(handleHit:)];
//			[self addSubview:handle];

			openButton = [BBImageButtonFactory openCloseButtonInRect:handleRect];
			[openButton setTarget:self];
			[openButton setAction:@selector(handleHit:)];
			[self addSubview:openButton];
			[openButton retain];
			
			
			
			isOut = NO;
			// add the various views
			// the background is a PNG image. load it
			background = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"tallLibTab" ofType:@"png"]];
			//TODO: make the background an NSImageView instead of drawing it every time
			
			// the view holder is a clear view that holds all the nodeviews and displays on top of the background
			// we use a holder view so that we can cause a scrolling event
			NSRect holder = [self bounds];
			holder.origin.x += NSMaxX(handleRect) + 19;
			holder.origin.y += 5;
			holder.size.height -= 110;
			holder.size.width -= 190;
			viewHolder = [[NSView alloc] initWithFrame:holder];
			[self addSubview:viewHolder];
			[self initNodeViews];
			
			verticalOffset = 0;
			
			// the drag strip sits to the side and allows us to control the scrolling of 
			// the holder view.  it is more like iPhone scrolling less like desktop scrollbar scrolling
			NSRect dragRect = NSMakeRect(NSMaxX(holder) + 10, NSMinY(holder), 40, NSHeight(holder));
			BBDragStrip * draggy = [[BBDragStrip alloc] initWithFrame:dragRect];
			[draggy setDelegate:self];
			[self addSubview:draggy];
			// now add all the buttons

			float buttonSize = 40.0;
			float buttonleftInset = NSMaxX(handleRect) + 19;
			float edge = 6.0;
			
			NSRect buttonRect = NSMakeRect(NSMinX(self.bounds) + buttonleftInset , NSMaxY([self bounds]) - (buttonSize + edge) - 5, buttonSize, buttonSize);
			float buttonBorder = 45.0;
			
			NSButton * button1 = [BBImageButtonFactory imageButtonInRect:buttonRect withImageName:@"one"];
			[button1 setTarget:self];
			[button1 setAction:@selector(oneClick)];
			[self addSubview:button1];
			
			buttonRect.origin.x += buttonBorder;
			
			NSButton * button2 = [BBImageButtonFactory imageButtonInRect:buttonRect withImageName:@"two"];
			[button2 setTarget:self];
			[button2 setAction:@selector(twoClick)];
			[self addSubview:button2];
			
			buttonRect.origin.x += buttonBorder;
			
			NSButton * button3 = [BBImageButtonFactory imageButtonInRect:buttonRect withImageName:@"three"];
			[button3 setTarget:self];
			[button3 setAction:@selector(threeClick)];
			[self addSubview:button3];
    
			buttonRect = NSMakeRect(NSMinX(self.bounds) + buttonleftInset , NSMinY(buttonRect) - (buttonSize + edge), buttonSize, buttonSize);
			
			NSButton * button4 = [BBImageButtonFactory bulbButtonInRect:buttonRect];
			[button4 setTarget:self];
			[button4 setAction:@selector(bulbClick)];
			[self addSubview:button4];
			
			buttonRect.origin.x += buttonBorder;
			
			NSButton * button5 = [BBImageButtonFactory connectionButtonInRect:buttonRect];
			[button5 setTarget:self];
			[button5 setAction:@selector(connectClick)];
			[self addSubview:button5];
			
			
			buttonRect.origin.x += buttonBorder;
			
			NSButton * button6 = [BBImageButtonFactory magnifierButtonInRect:buttonRect];
			[button6 setTarget:self];
			[button6 setAction:@selector(zoomClick)];
			[self addSubview:button6];
			
			
			buttonRect.origin.x += buttonBorder;
			buttonRect.origin.y += NSHeight(buttonRect)/2.0;
			
			NSButton * button7 = [BBImageButtonFactory quitButtonInRect:buttonRect];
			[button7 setTarget:self];
			[button7 setAction:@selector(quitClick)];
			[self addSubview:button7];
			
			
			dragRect.origin.y = NSMinY(buttonRect) - edge;
			dragRect.size.height = (buttonSize * 2.0) + (edge * 3.0);
			BBDragStrip * draggy2 = [[BBDragStrip alloc] initWithFrame:dragRect];
		//	[self addSubview:draggy2];

			
			
			NSRect f = [self frame];
			tabInX = f.origin.x;
			tabOutX = f.origin.x - 190;
			
			
		}
    return self;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
	float posFactor = [[NSUserDefaults standardUserDefaults] floatForKey:@"BBLibraryButtonPosition"];
	
	handleRect = NSMakeRect(0, (NSHeight([self bounds]) * posFactor) - 22.5, 45, 45);
	[openButton setFrame:handleRect];
}



-(void)addNodeView:(BBNode*)aNode
{
	[self addNodeView:aNode animate:NO];
}

// removes a node view
-(void)removeNodeView:(BBNode*)aNode
{
	BOOL shift = NO;
	float shiftHeight;
	BBLibraryNodeView * toKill;
	// go through all the nodes. once i find teh one i want
	// calc the height to shift all the rest of them
	// set a flag and shift all the views after it in the list
	for (BBLibraryNodeView* view in [viewHolder subviews]) {
		NSRect frame = [view frame];
		// figure out how much to shift 
		if (shift) {
			frame.origin.y -= shiftHeight;
			[[view animator] setFrame:frame];
		}
		if (view.node == aNode) {
			shiftHeight = NSHeight(frame) + 15;
			toKill = view;
			shift = YES;
		}
	}	
	// now remove the one i want to kill
	[toKill removeFromSuperview];
}

// add a node, make a nice animation
-(void)addNodeView:(BBNode*)aNode animate:(BOOL)animate 
{
	NSRect trashRect = NSMakeRect(0, 0, 100, 100);
	// libnodeviews set their own size, so just init it with any old rect
	BBLibraryNodeView * nView = [[BBLibraryNodeView alloc] initWithFrame:trashRect];
	[nView setNode:aNode];
	// reset the view frame to size itself
	[nView resetFrame];
	// now get the frame so I can position it
	NSRect frame = [nView frame];
	frame.origin = nextNodePostion;
	[nView setFrame:frame];
	
	// ad it to my view
	[viewHolder addSubview:nView];	

	// increment the position counter
	nextNodePostion.y += NSHeight(frame) + 15;

	// now animate.  shift the view so that the one i just added is at the top
	// ie the next position (which is above the added view) minus the height of our 
	// background image (because the scroll is calced from the bottom)
	if (animate)
		[self adjustVertical:nextNodePostion.y - 600 animate:YES];
	
	[self setNeedsDisplay:YES];
}

// goes through and resets all the positions.
// this is used if one is taken out or something
-(void)resetNodeViewPositionsAnimate:(BOOL)animate
{
	// our default starting point
	nextNodePostion = NSMakePoint(0,15);

	// go through all my subviews, and reset the library nodes
	for (BBLibraryNodeView* subby in [viewHolder subviews]) {
			NSRect frame = [subby frame];
			frame.origin.y = nextNodePostion.y;
			if (animate) {
				[[subby animator] setFrame:frame];
			} else {
				[subby setFrame:frame];				
			}
			// increment with border
			nextNodePostion.y += NSHeight(frame) + 15;
	}
}

-(void)initNodeViews
{
	// add the nodes the first time
	nextNodePostion = NSMakePoint(0,15);
	// now draw the mini images
	for (BBNode* node in [BBLibraryController libraryNodes]) {
		[self addNodeView:node];
	}
}

- (void)drawRect:(NSRect)rect 
{
	// for now, just draw the background image
//	NSSize iSize = [background size];
//	[background drawInRect:NSMakeRect(0, 0, iSize.width, iSize.height - 2) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:0.65];
	
	NSRect back = [self bounds];
	back.origin.x = NSMaxX(handleRect) + 7;
	back = NSInsetRect(back, 2, 2);
	back = [self centerScanRect:back];
	NSBezierPath * rounded = [NSBezierPath bezierPathWithRoundedRect:back xRadius:8 yRadius:8];
	[[NSColor colorWithDeviceWhite:0.0 alpha:0.65] set];
	[rounded fill];
	[[NSColor whiteColor] set];
	[rounded stroke];
	
	float yOffset = NSMaxY([self bounds]) - 104.0;
	NSPoint a = NSMakePoint(NSMaxX(handleRect) + 9.0, yOffset);
	NSPoint b = NSMakePoint(NSMaxX([self bounds]), yOffset);
	NSBezierPath * divider = [NSBezierPath bezierPath];
	[divider moveToPoint:a];
	[divider lineToPoint:b];
	[divider setLineWidth:2.0];
	[[NSColor grayColor] set];
	[divider stroke];
	
//	[[NSColor redColor] set];
//	[NSBezierPath strokeRect:handleRect];	
}

// the mousedown just looks for hits to the tab button
// TODO: make this a transparent button

-(void)otherMouseDown:(NSEvent*)theEvent
{
	[self mouseDown:theEvent];
}

-(void)handleHit:(id)sender
{		
	if (isOut) {
		[self closeTab];
	} else {
		[self openTab];
	}
}

-(void)openTab
{
	NSRect f = [self frame];
	isOut = YES;
	f.origin.x = tabOutX;
	[[self animator] setFrame:f];
}

-(void)closeTabNotification:(id)sender
{
	if (isOut) 	[openButton performClick:self];
}

-(void)closeTab
{
	NSRect f = [self frame];
	f.origin.x = tabInX;
	isOut = NO;	
	[[self animator] setFrame:f];
}


// just a convenience method
-(void)adjustVertical:(float)f
{
	[self adjustVertical:f animate:NO];
}

// this is how the drag view causes scrolling
-(void)adjustVertical:(float)f animate:(BOOL)b
{
	// first check to see if we are at the bottom, done want to go any further
	if ((verticalOffset + f) < 0) return;
	verticalOffset += f;
	// then just shift all the frames
	for (NSView* view in [viewHolder subviews]) {
		NSRect frame = [view frame];
		frame.origin.y -= f;
		if (b) {
			[[view animator] setFrame:frame];
		} else {
			[view setFrame:frame];			
		}
	}
	// set the node position increment
	nextNodePostion.y -= f;
	[self setNeedsDisplay:YES];
}


-(NSView*)libHitTest:(NSPoint)p{
	// special case of a hit test
	NSPoint mouseDown = [[[self window] contentView] convertPoint:p toView:self];
	return [self hitTest:p];
}

-(void)oneClick
{
	[openButton performClick:self];
	NSString * filename = [[NSUserDefaults standardUserDefaults] objectForKey:@"BBScene1FileName"];
	if (![[NSFileManager defaultManager] fileExistsAtPath:filename isDirectory:NO]) return;
	[[BBAppController sharedAppController] loadFromFile:filename];
}

-(void)twoClick
{
	[openButton performClick:self];
	NSString * filename = [[NSUserDefaults standardUserDefaults] objectForKey:@"BBScene2FileName"];
	if (![[NSFileManager defaultManager] fileExistsAtPath:filename isDirectory:NO]) return;
	[[BBAppController sharedAppController] loadFromFile:filename];
}

-(void)threeClick
{
	[openButton performClick:self];
	NSString * filename = [[NSUserDefaults standardUserDefaults] objectForKey:@"BBScene3FileName"];
	if (![[NSFileManager defaultManager] fileExistsAtPath:filename isDirectory:NO]) return;
	[[BBAppController sharedAppController] loadFromFile:filename];
}

-(void)zoomClick
{
	[openButton performClick:self];
	[[NSNotificationCenter defaultCenter] postNotificationName:@"BBZoomNotification" object:[NSNumber numberWithFloat:1.0]];
}

-(void)connectClick
{
	[openButton performClick:self];
	// turn on the connections
	[[NSNotificationCenter defaultCenter] postNotificationName:@"BBToggleConnected" object:self];
}

-(void)bulbClick
{
	[openButton performClick:self];
	[[NSNotificationCenter defaultCenter] postNotificationName:@"BBDiscloseConnected" object:self];
	[[NSNotificationCenter defaultCenter] postNotificationName:@"BBHighlightConnected" object:self];
}

-(void)quitClick
{
	[openButton performClick:self];
	[[BBAppController sharedAppController] launchOther:self];
}


- (void) dealloc
{
	[openButton release];
	[background release];
	[viewHolder release];
	[super dealloc];
}


@end
